home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / MacPerl 4.1.3 / MacPerl / MPDrop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-04  |  7.5 KB  |  223 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPDrop.c            -    Droplets
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C
  6.  
  7. $Log: MPDrop.c,v $
  8. Revision 1.2  1994/05/04  02:50:15  neeri
  9. Debugger support.
  10.  
  11. Revision 1.1  1994/02/27  23:00:19  neeri
  12. Initial revision
  13.  
  14. Revision 0.1  1993/10/02  00:00:00  neeri
  15. Compiles correctly
  16.  
  17. *********************************************************************/
  18.  
  19. #include <Dialogs.h>
  20. #include <QuickDraw.h>
  21. #include <Windows.h>
  22. #include <Menus.h>
  23. #include <Fonts.h>
  24. #include <AppleEvents.h>
  25. #include <AERegistry.h>
  26. #include <Processes.h>
  27. #include <files.h>
  28. #include <StandardFile.h>
  29. #include <Aliases.h>
  30. #include <GestaltEqu.h>
  31. #include <Folders.h>
  32. #include <Errors.h>
  33. #include <Resources.h>
  34.  
  35. #pragma segment Main
  36.  
  37. #define FAILOSERR(call) if (err = call) return err; else 0
  38.  
  39. Boolean        gQuitting;
  40. FSSpec        gMySelf;
  41. EventRecord    gLastEvent;
  42.  
  43. pascal Boolean CheckEnvironment()
  44. {
  45.     long    result;
  46.     
  47.     if (Gestalt(gestaltAppleEventsAttr, &result))
  48.         return false;
  49.         
  50.     return (result & (1 << gestaltAppleEventsPresent)) != 0;
  51. }  /* CheckEnvironment */
  52.  
  53. /* The following stuff is adapted from Jens Peter Alfke's SignatureToApp code */
  54.  
  55. OSErr MacPerlRunning(ProcessSerialNumber *psn)
  56. {
  57.     OSErr err;
  58.     ProcessInfoRec info;
  59.     
  60.     psn->highLongOfPSN = 0;
  61.     psn->lowLongOfPSN  = kNoProcess;
  62.     do    {
  63.         FAILOSERR(GetNextProcess(psn));
  64.             
  65.         info.processInfoLength     = sizeof(info);
  66.         info.processName             = nil;
  67.         info.processAppSpec         = nil;
  68.         
  69.         FAILOSERR(GetProcessInformation(psn, &info));
  70.     } while(info.processSignature != 'McPL');
  71.  
  72.     *psn = info.processNumber;
  73.     
  74.     return noErr;
  75. }
  76.  
  77. OSErr GetSysVolume(short *vRefNum)
  78. {
  79.     long dir;
  80.     
  81.     return FindFolder(kOnSystemDisk, kSystemFolderType, false, vRefNum, &dir);
  82. }
  83.  
  84. OSErr GetIndVolume(short index, short *vRefNum)
  85. {
  86.     OSErr             err;
  87.     ParamBlockRec     pb;
  88.     
  89.     pb.volumeParam.ioNamePtr     = nil;
  90.     pb.volumeParam.ioVolIndex     = index;
  91.     
  92.     FAILOSERR(PBGetVInfoSync(&pb));
  93.     
  94.     *vRefNum = pb.volumeParam.ioVRefNum;
  95.     
  96.     return noErr;
  97. }
  98.  
  99. OSErr VolHasDesktopDB(short vRefNum, Boolean * hasDesktop)
  100. {
  101.     OSErr                         err;
  102.     HParamBlockRec             pb;
  103.     GetVolParmsInfoBuffer     info;
  104.     
  105.     pb.ioParam.ioNamePtr     = nil;
  106.     pb.ioParam.ioVRefNum     = vRefNum;
  107.     pb.ioParam.ioBuffer         = (Ptr)&info;
  108.     pb.ioParam.ioReqCount     = sizeof(GetVolParmsInfoBuffer);
  109.     
  110.     FAILOSERR(PBHGetVolParmsSync(&pb));
  111.  
  112.     *hasDesktop = (info.vMAttrib & (1 << bHasDesktopMgr))!=0;
  113.     
  114.     return noErr;
  115. }
  116.  
  117. OSErr FindAppOnVolume(short vRefNum, FSSpec *file)
  118. {
  119.     OSErr     err;
  120.     DTPBRec     pb;
  121.     
  122.     /* Get Acess path to Desktop database on this volume */
  123.     
  124.     pb.ioVRefNum         = vRefNum;
  125.     pb.ioNamePtr         = nil;
  126.     FAILOSERR(PBDTGetPath(&pb));
  127.     
  128.     pb.ioIndex             = 0;
  129.     pb.ioFileCreator     = 'McPL';
  130.     pb.ioNamePtr         = file->name;
  131.     switch (err = PBDTGetAPPLSync(&pb))    {
  132.     case noErr:
  133.         file->vRefNum     = vRefNum;
  134.         file->parID     = pb.ioAPPLParID;
  135.     
  136.         return noErr;
  137.     case fnfErr:
  138.         return afpItemNotFound;                        /* Bug in PBDTGetAPPL            */
  139.     default:
  140.         return err;
  141.     }
  142. }
  143.  
  144. OSErr LaunchIt(FSSpecPtr fileSpec, ProcessSerialNumber * psn )
  145. {
  146.     OSErr                     err;
  147.     LaunchParamBlockRec     pb;
  148.     
  149.     pb.launchBlockID             = extendedBlock;
  150.     pb.launchEPBLength         = extendedBlockLen;
  151.     pb.launchFileFlags         = launchNoFileFlags;
  152.     pb.launchControlFlags    = launchContinue + launchNoFileFlags;
  153.     pb.launchAppSpec             = fileSpec;
  154.     pb.launchAppParameters    = nil;
  155.     
  156.     FAILOSERR(LaunchApplication(&pb));
  157.  
  158.     *psn = pb.launchProcessSN;
  159.     
  160.     return noErr;
  161. }
  162.  
  163. /* Get the psn ofa copy of MacPerl. Launch one if necessary. Buy one. Steal one. */
  164. static OSErr LaunchMacPerl(ProcessSerialNumber *psn)
  165. {
  166.     OSErr     err;
  167.     short     vRefNum, sysVRefNum, index;
  168.     FSSpec     file;
  169.     Boolean     hasDesktopDB;
  170.     
  171.     /* See if ToolServer is already running:                    */
  172.     err    = MacPerlRunning(psn);
  173.     
  174.     if    (err != procNotFound)
  175.         return err;
  176.     
  177.     /* Not running, try to launch it */
  178.     
  179.     FAILOSERR(GetSysVolume(&sysVRefNum));
  180.     
  181.     vRefNum = sysVRefNum;
  182.     
  183.     for (index = 0; !err; err = GetIndVolume(++index,&vRefNum)) {
  184.         if (!index || vRefNum != sysVRefNum) {
  185.             if (err = VolHasDesktopDB(vRefNum,&hasDesktopDB))
  186.                 return err;
  187.                 
  188.             if (hasDesktopDB)    
  189.                 switch (err = FindAppOnVolume(vRefNum, &file))    {
  190.                 case noErr:
  191.                     return LaunchIt(&file, psn);
  192.                 case afpItemNotFound:
  193.                     break;
  194.                 default:
  195.                     return err;
  196.                 }
  197.         }
  198.     }
  199.     
  200.     switch (err) {
  201.     case nsvErr:
  202.     case afpItemNotFound:
  203.         return fnfErr;
  204.     default:
  205.         return err;
  206.     }
  207. }
  208.  
  209. void WhoAmI(FSSpec * me)
  210. {
  211.     FCBPBRec        fcb;
  212.     
  213.     fcb.ioNamePtr    =    &me->name;
  214.     fcb.ioRefNum    =    CurResFile();
  215.     fcb.ioFCBIndx    =    0;
  216.     
  217.     PBGetFCBInfoSync(&fcb);
  218.     
  219.     me->vRefNum    =    fcb.ioFCBVRefNum;
  220.     me->parID    =    fcb.ioFCBParID;
  221. }
  222.  
  223. pascal OSErr Yo(cons